package com.lushu.chapitre1.dialogue
{
    import com.lushu.chapitre1.dialogue.api.INode;
    import com.lushu.chapitre1.dialogue.nodes.ActionNode;
    import com.lushu.chapitre1.dialogue.nodes.ComplexTextNode;
    import com.lushu.chapitre1.dialogue.nodes.ConditionListNode;
    import com.lushu.chapitre1.dialogue.nodes.ConditionNode;
    import com.lushu.chapitre1.dialogue.nodes.DefaultNode;
    import com.lushu.chapitre1.dialogue.nodes.DialogueNode;
    import com.lushu.chapitre1.dialogue.nodes.ElseIfNode;
    import com.lushu.chapitre1.dialogue.nodes.ElseNode;
    import com.lushu.chapitre1.dialogue.nodes.IfNode;
    import com.lushu.chapitre1.dialogue.nodes.JoueurNode;
    import com.lushu.chapitre1.dialogue.nodes.LieuNode;
    import com.lushu.chapitre1.dialogue.nodes.NpcNode;
    import com.lushu.chapitre1.dialogue.nodes.SayNode;
    import com.lushu.chapitre1.dialogue.nodes.SubConditionNode;
    import com.lushu.chapitre1.dialogue.nodes.SwitchNode;
    import com.lushu.chapitre1.dialogue.nodes.TextNode;
    import com.lushu.chapitre1.dialogue.nodes.subAction.AddItemAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.AddQuestAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.BuildExtensionAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.BuyHouseAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.GetCourrierAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.OpenCoiffeurAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.OpenSellingAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.OpenShopAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.RemoveItemAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.SendCourrierAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.SetBetAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.SetChasaAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.SetQuestAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.SetVacancesAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.UpdateAffectionAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.UpdateGleetPatasAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.UpdatePatasAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.UpgradeExtensionAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.UpgradeHouseAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.WarpAction;
    import com.lushu.chapitre1.dialogue.nodes.subAction.WarpRegionAction;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.EmptySubCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasAffectionNpcCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasAnimalCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasBetRaceCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasBoughtItemCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasChasaCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasChasaForDaysCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasCourrierCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasGleetPataCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasGrainesCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasItemCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasJobLevelCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasPataCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasPoissonCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasRecetteCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasSoldForPatasCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasSoldItemCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasTalkedCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.HasWonRaceCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.IsDateBetweenCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.IsDateCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.IsRaceInCondition;
    import com.lushu.chapitre1.dialogue.nodes.subCondition.SexeCondition;

    public class NodeFactory
    {
        private static var lushu:Namespace = new Namespace("http://code.google.com/p/shining-fluff-devkit/SFDK");

        public static function getDialogueFromXML(xmlData:XML):INode {
            try {
                default xml namespace = lushu;

                var node:INode;

                node = traiteContainer(xmlData..normal[0]);
                node.name = "Normal";
                return node;
            }
            catch(e:Error) {
                trace(e);
            }
            return null;
        }

        private static function traiteContainer(currentXML:XML):INode {
            var currentNodeXML:XML = currentXML;
            var name:String = currentNodeXML.localName();
            var currentNode:INode;
            switch (name) {
                case "condition" :
                    currentNode = new ConditionNode();
                    break;

                case "npc" :
                    currentNode = new NpcNode();
                    break;

                case "dialogue" :
                    currentNode = new DialogueNode();
                    break;

                case "switch" :
                    currentNode = new SwitchNode();
                    break;

                case "lieu" :
                    currentNode = new LieuNode();
                    break;

                case "if" :
                    currentNode = new IfNode();
                    break;

                case "joueur" :
                    currentNode = new JoueurNode();
                    break;

                case "else" :
                    currentNode = new ElseNode();
                    break;

                case "elseif" :
                    currentNode = new ElseIfNode();
                    break;

                default:
                    currentNode = new DefaultNode(name);
                    break;
            }

            if (currentNode != null) {
                currentNode.setInformation(currentNodeXML);

                var containerChildren:XMLList = currentNodeXML.children();
                var currentElement:XML;
                var currentElementName:String;
                var i:int, childrenLength:int = containerChildren.length();

                for (i = 0; i < childrenLength; i++) {
                    currentElement = containerChildren[i];
                    currentElementName = currentElement.localName();

                    switch (currentElementName) {
                        case "say" :
                            currentNode.addChild(traiteSay(currentElement));
                            break;

                        case "text" :
                            currentNode.addChild(traiteText(currentElement));
                            break;

                        case "condition" :
                        case "if" :
                        case "else" :
                        case "elseif" :
                        case "joueur" :
                        case "npc" :
                        case "lieu" :
                        case "dialogue":
                        case "switch":
                            currentNode.addChild(traiteContainer(currentElement));
                            break;

                        case "cText" :
                            currentNode.addChild(traiteComplexText(currentElement));
                            break;

                        case "conditionList" :
                            currentNode.addChild(traiteConditionList(currentElement));
                            break;
                    }
                }
            }
            return currentNode;
        }

        private static function traiteComplexText(xmlContent:XML):INode {
            var currentNode:ComplexTextNode = new ComplexTextNode();
            currentNode.setInformation(xmlContent);

            var containerChildren:XMLList = xmlContent.children();
            var currentElement:XML;
            var currentElementName:String;
            var i:int, childrenLength:int = containerChildren.length();

            currentElement = containerChildren[0];
            currentElementName = currentElement.localName();
            if (currentElementName == "text")
                currentNode.addChild(traiteText(currentElement));

            for (i = 1; i < childrenLength; i++) {
                currentElement = containerChildren[i];
                currentElementName = currentElement.localName();
                var actionNode:ActionNode;

                if (currentElementName == "updateAffection")
                    actionNode = new UpdateAffectionAction();
                if (currentElementName == "updatePatas")
                    actionNode = new UpdatePatasAction();
                if (currentElementName == "updateGleetPatas")
                    actionNode = new UpdateGleetPatasAction();
                if (currentElementName == "addItem")
                    actionNode = new AddItemAction();
                if (currentElementName == "removeItem")
                    actionNode = new RemoveItemAction();
                if (currentElementName == "setChasa")
                    actionNode = new SetChasaAction();
                if (currentElementName == "addQuest")
                    actionNode = new AddQuestAction();
                if (currentElementName == "setQuest")
                    actionNode = new SetQuestAction();
                if (currentElementName == "setBet")
                    actionNode = new SetBetAction();
                if (currentElementName == "openShop")
                    actionNode = new OpenShopAction();
                if (currentElementName == "warp")
                    actionNode = new WarpAction();
                if (currentElementName == "warpRegion")
                    actionNode = new WarpRegionAction();
                if (currentElementName == "sendCourrier")
                    actionNode = new SendCourrierAction();
                if (currentElementName == "getCourrier")
                    actionNode = new GetCourrierAction();
                if (currentElementName == "buildExtension")
                    actionNode = new BuildExtensionAction();
                if (currentElementName == "upgradeExtension")
                    actionNode = new UpgradeExtensionAction();
                if (currentElementName == "buyHouse")
                    actionNode = new BuyHouseAction();
                if (currentElementName == "upgradeHouse")
                    actionNode = new UpgradeHouseAction();
                if (currentElementName == "openCoiffeur")
                    actionNode = new OpenCoiffeurAction();
                if (currentElementName == "openSelling")
                    actionNode = new OpenSellingAction();
                if (currentElementName == "setVacances")
                    actionNode = new SetVacancesAction();

                actionNode.setInformation(containerChildren[i]);

                currentNode.addChild(actionNode);
            }
            return currentNode;
        }

        private static function traiteConditionList(xmlContent:XML):INode {
            var currentNode:ConditionListNode = new ConditionListNode();
            currentNode.setInformation(xmlContent);

            var containerChildren:XMLList = xmlContent.children();
            var currentElement:XML;
            var currentElementName:String;
            var i:int, childrenLength:int = containerChildren.length();

            if (childrenLength == 0)
                currentNode.addChild(new EmptySubCondition());
            for (i = 0; i < childrenLength; i++) {
                currentElement = containerChildren[i];
                currentElementName = currentElement.localName();
                var conditionNode:SubConditionNode;

                if (currentElementName == "hasItem")
                    conditionNode = new HasItemCondition();
                if (currentElementName == "hasChasa")
                    conditionNode = new HasChasaCondition();
                if (currentElementName == "hasRecette")
                    conditionNode = new HasRecetteCondition();
                if (currentElementName == "hasPata")
                    conditionNode = new HasPataCondition();
                if (currentElementName == "hasPoisson")
                    conditionNode = new HasPoissonCondition();
                if (currentElementName == "hasGleetPata")
                    conditionNode = new HasGleetPataCondition();
                if (currentElementName == "hasSoldForPatas")
                    conditionNode = new HasSoldForPatasCondition();
                if (currentElementName == "hasBoughtItem")
                    conditionNode = new HasBoughtItemCondition();
                if (currentElementName == "hasSoldItem")
                    conditionNode = new HasSoldItemCondition();
                if (currentElementName == "hasTalked")
                    conditionNode = new HasTalkedCondition();
                if (currentElementName == "hasCourrier")
                    conditionNode = new HasCourrierCondition();
                if (currentElementName == "hasBetRace")
                    conditionNode = new HasBetRaceCondition();
                if (currentElementName == "hasWonRace")
                    conditionNode = new HasWonRaceCondition();
                if (currentElementName == "hasAffectionNpc")
                    conditionNode = new HasAffectionNpcCondition();
                if (currentElementName == "hasChasaForDays")
                    conditionNode = new HasChasaForDaysCondition();
                if (currentElementName == "sexe")
                    conditionNode = new SexeCondition();
                if (currentElementName == "hasJobLevel")
                    conditionNode = new HasJobLevelCondition();
                if (currentElementName == "isDate")
                    conditionNode = new IsDateCondition();
                if (currentElementName == "isDateBetween")
                    conditionNode = new IsDateBetweenCondition();
                if (currentElementName == "hasGraines")
                    conditionNode = new HasGrainesCondition();
                if (currentElementName == "hasAnimal")
                    conditionNode = new HasAnimalCondition();
                if (currentElementName == "isRaceIn")
                    conditionNode = new IsRaceInCondition();

                conditionNode.setInformation(containerChildren[i]);

                currentNode.addChild(conditionNode);
            }
            return currentNode;
        }

        private static function traiteSay(xmlContent:XML):INode {
            var sayNode:SayNode = new SayNode();
            sayNode.setInformation(xmlContent);
            return sayNode;
        }

        private static function traiteText(xmlContent:XML):INode {
            var textNode:TextNode = new TextNode();
            textNode.setInformation(xmlContent);
            return textNode;
        }
    }
}